home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / dev / c / vbcc.lha / vbcc / statements.c < prev    next >
C/C++ Source or Header  |  1998-02-19  |  30KB  |  880 lines

  1. /*  $VER: vbcc (statements.c) V0.4  */
  2.  
  3. #include "vbc.h"
  4.  
  5. static char FILE_[]=__FILE__;
  6.  
  7. int cont_label=0;
  8. int test_assignment(struct Typ *,np);
  9.  
  10. #define cr()
  11. #ifndef cr
  12. void cr(void)
  13. /*  tested Registerbelegung */
  14. {
  15.     int i;
  16.     for(i=0;i<=MAXR;i++)
  17.         if(regs[i]!=regsa[i]) {error(149,regnames[i]);regs[i]=regsa[i];}
  18. }
  19. #endif
  20. void statement(void)
  21. /*  bearbeitet ein statement                                    */
  22. {
  23.     char *merk;
  24.     cr();
  25.     killsp();
  26.     if(*s=='{'){
  27.         enter_block();
  28.         if(nesting>0) local_offset[nesting]=local_offset[nesting-1];
  29.         compound_statement();leave_block();return;
  30.     }
  31.     merk=s;
  32.     cpbez(buff,0);
  33.     if(!strcmp("if",buff)){if_statement();return;}
  34.     if(!strcmp("switch",buff)){switch_statement();return;}
  35.     if(!strcmp("for",buff)){for_statement();return;}
  36.     if(!strcmp("while",buff)){while_statement();return;}
  37.     if(!strcmp("do",buff)){do_statement();return;}
  38.     if(!strcmp("goto",buff)){goto_statement();return;}
  39.     if(!strcmp("continue",buff)){continue_statement();return;}
  40.     if(!strcmp("break",buff)){break_statement();return;}
  41.     if(!strcmp("return",buff)){return_statement();return;}
  42.     if(!strcmp("case",buff)){labeled_statement();return;}
  43.     killsp();if(*s==':'){labeled_statement();return;}
  44.     /*  fehlt Aufruf der anderen statements */
  45.     s=merk;
  46.     expression_statement();
  47. }
  48. void labeled_statement(void)
  49. /*  bearbeitet labeled_statement                                */
  50. {
  51.     struct llist *lp;int def=0;
  52.     nocode=0;
  53.     if(*s==':'){
  54.         s++;
  55.         if(!*buff){error(130);return;}
  56.         if(!strcmp("default",buff)){def=1;lp=0;} else lp=find_label(buff);
  57.         if(lp&&lp->flags&LABELDEFINED){error(131,buff);return;}
  58.         if(!lp) lp=add_label(buff);
  59.         lp->flags|=LABELDEFINED;
  60.         lp->switch_count=0;
  61.         if(def){
  62.             if(switch_act==0) error(150);
  63.             lp->flags|=LABELDEFAULT;
  64.             lp->switch_count=switch_act;
  65.         }
  66.         gen_label(lp->label);
  67.         afterlabel=0;
  68.     }else{
  69.         /*  case    */
  70.         np tree;struct llist *lp;
  71.         tree=expression();
  72.         killsp();
  73.         if(*s==':'){s++;killsp();} else error(70);
  74.         if(!switch_count){
  75.             error(132);
  76.         }else{
  77.             if(!tree||!type_expression(tree)){
  78.             }else{
  79.                 if(tree->flags!=CEXPR||tree->sidefx){
  80.                     error(133);
  81.                 }else{
  82.                     if((tree->ntyp->flags&NQ)<CHAR||(tree->ntyp->flags&NQ)>LONG){
  83.                         error(134);
  84.                     }else{
  85.                         lp=add_label(empty);
  86.                         lp->flags=LABELDEFINED;
  87.                         lp->switch_count=switch_act;
  88.                         eval_constn(tree);
  89.                         if(switch_typ==CHAR) lp->val.vchar=vchar;
  90.                         if(switch_typ==(UNSIGNED|CHAR)) lp->val.vuchar=vuchar;
  91.                         if(switch_typ==SHORT) lp->val.vshort=vshort;
  92.                         if(switch_typ==(UNSIGNED|SHORT)) lp->val.vushort=vushort;
  93.                         if(switch_typ==INT) lp->val.vint=vint;
  94.                         if(switch_typ==(UNSIGNED|INT)) lp->val.vuint=vuint;
  95.                         if(switch_typ==LONG) lp->val.vlong=vlong;
  96.                         if(switch_typ==(UNSIGNED|LONG)) lp->val.vulong=vulong;
  97.                         if(switch_typ==POINTER) lp->val.vpointer=vpointer;
  98.                         gen_label(lp->label);
  99.                     }
  100.                 }
  101.             }
  102.         }
  103.         if(tree) free_expression(tree);
  104.     }
  105.     cr();
  106.     killsp();
  107.     if(*s!='}') statement();
  108. }
  109. void if_statement(void)
  110. /*  bearbeitet if_statement                                     */
  111. {
  112.     int ltrue,lfalse,lout,cexpr,cm;char *merk,buff[MAXI];
  113.     np tree;struct IC *new;
  114.     killsp(); if(*s=='(') s++; else error(151);
  115.     killsp();cm=nocode;
  116.     tree=expression();
  117.     if(!tree) {error(135);
  118.     }else{
  119.         ltrue=++label;lfalse=++label;
  120.         if(type_expression(tree)){
  121.             tree=makepointer(tree);
  122.             if(!arith(tree->ntyp->flags&NQ)&&(tree->ntyp->flags&NQ)!=POINTER)
  123.                 {error(136);
  124.             }else{
  125.                 if(tree->flags==ASSIGN) error(164);
  126.                 gen_IC(tree,ltrue,lfalse);
  127.                 if(tree->flags==CEXPR){
  128.                     eval_const(&tree->val,tree->ntyp->flags&NU);
  129.                     if(zdeqto(vdouble,d2zd(0.0))&&zleqto(vlong,l2zl(0))&&zuleqto(vulong,ul2zul(0UL))) cexpr=2; else cexpr=1;
  130.                 }else cexpr=0;
  131.                 if((tree->o.flags&SCRATCH)&&cexpr) free_reg(tree->o.reg);
  132.                 if(tree->o.flags&&!cexpr){
  133.                     new=mymalloc(ICS);
  134.                     new->code=TEST;
  135.                     new->q1=tree->o;
  136.                     new->q2.flags=new->z.flags=0;
  137.                     new->typf=tree->ntyp->flags;
  138.                     add_IC(new);
  139.                     new=mymalloc(ICS);
  140.                     new->code=BEQ;
  141.                     new->typf=lfalse;
  142.                     add_IC(new);
  143.                 }
  144.                 if(cexpr==2){
  145.                     new=mymalloc(ICS);
  146.                     new->code=BRA;
  147.                     new->typf=lfalse;
  148.                     add_IC(new);
  149.                 }
  150.             }
  151.         }
  152.         free_expression(tree);
  153.     }
  154.     killsp(); if(*s==')') s++; else error(59);
  155.     if(cexpr==2) nocode=1;
  156.     if(!cexpr&&!tree->o.flags) gen_label(ltrue);
  157.     statement();
  158.     killsp();
  159.     merk=s;
  160.     cpbez(buff,0);
  161.     if(strcmp("else",buff)) {s=merk;nocode=cm;if(cexpr!=1) gen_label(lfalse);return;}
  162.     lout=++label;
  163.     if(cexpr!=2){
  164.         new=mymalloc(ICS);
  165.         new->code=BRA;
  166.         new->typf=lout;
  167.         add_IC(new);
  168.     }
  169.     if(cexpr!=1) {nocode=cm;gen_label(lfalse);}
  170.     if(cexpr==1) nocode=1; else nocode=cm;
  171.     statement();
  172.     nocode=cm;
  173.     if(cexpr!=2) gen_label(lout);
  174.     cr();
  175. }
  176. void switch_statement(void)
  177. /*  bearbeitet switch_statement                                 */
  178. {
  179.     np tree;int merk_typ,merk_count,merk_break;
  180.     struct IC *merk_fic,*merk_lic,*new;struct llist *lp,*l1,*l2;
  181.     killsp();
  182.     if(*s=='('){s++;killsp();} else error(151);
  183.     tree=expression(); killsp();
  184.     if(*s==')'){s++;killsp();} else error(59);
  185.     merk_typ=switch_typ;merk_count=switch_act;merk_break=break_label;
  186.     if(!tree){
  187.         error(137);
  188.     }else{
  189.         if(!type_expression(tree)){
  190.         }else{
  191.             if((tree->ntyp->flags&NQ)<CHAR||(tree->ntyp->flags&NQ)>LONG){
  192.                 error(138);
  193.             }else{
  194.                 int m1,m2,m3,def=0,rm,minflag;
  195.                 zlong l,ml,s;zulong ul,mul,us;
  196.                 if(tree->flags==ASSIGN) error(164);
  197.                 m3=break_label=++label;m1=switch_act=++switch_count;
  198.                 m2=switch_typ=tree->ntyp->flags&NU;
  199.                 gen_IC(tree,0,0);
  200.                 if((tree->o.flags&(DREFOBJ|SCRATCH))!=SCRATCH){
  201.                     new=mymalloc(ICS);
  202.                     new->code=ASSIGN;
  203.                     new->q1=tree->o;
  204.                     new->q2.flags=0;
  205.                     new->q2.val.vlong=sizetab[m2&NQ];
  206.                     get_scratch(&new->z,m2,0,0);
  207.                     new->typf=m2;
  208.                     tree->o=new->z;
  209.                     add_IC(new);
  210.                 }
  211.                 if((tree->o.flags&(SCRATCH|REG))==(SCRATCH|REG)){
  212.                     int r=tree->o.reg;
  213.                     rm=regs[r];
  214.                     regs[r]=regsa[r];
  215.                 }
  216.                 merk_fic=first_ic;merk_lic=last_ic;
  217.                 first_ic=last_ic=0;
  218.                 statement();
  219.                 if((tree->o.flags&(SCRATCH|REG))==(SCRATCH|REG)) regs[tree->o.reg]=rm;
  220.                 minflag=0;s=l2zl(0L);us=ul2zul(0UL);
  221.                 for(l1=first_llist;l1;l1=l1->next){
  222.                     if(l1->switch_count!=m1) continue;
  223.                     if(l1->flags&LABELDEFAULT){
  224.                         if(def) error(139);
  225.                         def=l1->label;
  226.                         continue;
  227.                     }
  228.                     lp=0;minflag&=~1;
  229.                     for(l2=first_llist;l2;l2=l2->next){
  230.                         if(l2->switch_count!=m1) continue;
  231.                         if(l2->flags